package com.sfj.common.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStream;
import java.util.*;

/**
 * @author kaka
 * @Date 2025/5/1
 */
public class JsonUtils {
    private static ObjectMapper objectMapper;

    private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class);

    static {
        objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        //objectMapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    }

    //pb3用 不抛异常
    public static <R> R parseObjectNoException(String json, Class<R> valueType) {
        try {
            return objectMapper.readValue(json, valueType);
        } catch (Exception e) {
            return null;
        }
    }

    public static <R> R parseObject(String json, Class<R> valueType) {
        try {
            return objectMapper.readValue(json, valueType);
        } catch (Exception e) {
            logger.warn("Initial Json deserialize failure:", e.getMessage());
            // 尝试进行类型判断处理
            if (List.class.isAssignableFrom(valueType) || ArrayList.class.isAssignableFrom(valueType)) {
                return tryParseWithCorrectJson(json, valueType, true);
            } else if (Map.class.isAssignableFrom(valueType) || HashMap.class.isAssignableFrom(valueType)
                    || LinkedHashMap.class.isAssignableFrom(valueType)) {
                return tryParseWithCorrectJson(json, valueType, false);
            }
            return null;
        }
    }

    private static <R> R tryParseWithCorrectJson(String json, Class<R> valueType, boolean isList) {
        try {
            // 尝试第一次使用fastjson直接解析
            return (R) (isList ? com.alibaba.fastjson.JSON.parseArray(json, valueType)
                    : com.alibaba.fastjson.JSON.parseObject(json, valueType));
        } catch (Exception ex1) {
            logger.warn("Json deserialize failure with fastjson, attempting to clean JSON:", ex1.getMessage());
            try {
                // 清洗 JSON 字符串
                String cleanedJson = correctJsonString(json);
                return (R) (isList ? com.alibaba.fastjson.JSON.parseArray(cleanedJson, valueType)
                        : com.alibaba.fastjson.JSON.parseObject(cleanedJson, valueType));
            } catch (Exception ex2) {
                logger.warn("Json deserialize failure after cleaning JSON:", ex2.getMessage());
                // 尝试将 JSON 解析为数组格式
                try {
                    String jsonArrayString = parseToJsonArray(json);
                    return (R) com.alibaba.fastjson.JSON.parseArray(jsonArrayString, valueType);
                } catch (Exception ex3) {
                    logger.warn("Json deserialize failure after attempting to parse as JSON array:", ex3.getMessage());
                }
            }
        }
        return null;
    }

    private static String correctJsonString(String jsonString) {
        String result = jsonString.replaceAll("\"\\[(.*?)\\]\"", "[$1]");
        return result;
    }

    private static String parseToJsonArray(String input) {
        return "[\"" + input.substring(1, input.length() - 1).replaceAll("\\s*,\\s*", "\",\"") + "\"]";
    }

    public static <R> R parseObject(byte[] json, Class<R> valueType) {
        try {
            return objectMapper.readValue(json, valueType);
        } catch (Exception e) {
            logger.warn("Json deserialize failure:", e.getMessage());
            return null;
        }
    }

    public static <R> R parseObject(InputStream in, Class<R> valueType) {
        try {
            return objectMapper.readValue(in, valueType);
        } catch (Exception e) {
            logger.warn("Json deserialize failure:", e.getMessage());
            return null;
        }
    }


    public static <R> Collection<R> parseArray(String json, Class<? extends Collection> collectionClass, Class<R> valueType) {
        try {
            return objectMapper.readValue(json, objectMapper.getTypeFactory().constructParametricType(Collection.class, collectionClass, valueType));
        } catch (Exception e) {
            logger.warn("Json deserialize failure .", e.getMessage());
            return null;
        }
    }

    public static <R> Collection<R> parseArray(InputStream in, Class<? extends Collection> collectionClass, Class<R> valueType) {
        try {
            return objectMapper.readValue(in, objectMapper.getTypeFactory().constructParametricType(Collection.class, collectionClass, valueType));
        } catch (Exception e) {
            logger.warn("Json deserialize failure .", e.getMessage());
            return null;
        }
    }


    public static String toJson(Object obj) {
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            logger.error("Json serialize failure .", e.getMessage());
            return null;
        }
    }

    public static String toJson(Map map) {
        try {
            return objectMapper.writeValueAsString(map);
        } catch (JsonProcessingException e) {
            logger.error("Json serialize failure .", e.getMessage());
            return null;
        }
    }

    public static String toJsonString(Object obj) {
        return JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect);
    }
}

